home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Languages / Masm V6.11 / SAMPLES / NTSAMPLE / THREADS / THREADS.C$ / THREADS.bin
Encoding:
Text File  |  1993-07-26  |  10.1 KB  |  344 lines

  1. /******************************************************************************\
  2. *       This is a part of the Microsoft Source Code Samples.
  3. *       Copyright (C) 1993 Microsoft Corporation.
  4. *       All rights reserved.
  5. *       This source code is only intended as a supplement to
  6. *       Microsoft Development Tools.
  7. *        Sample borrowed from Microsoft Visual C++ 1.00 for Microsoft Windows NT. 
  8. \******************************************************************************/
  9.  
  10. /*************************************************************************\
  11. *  PROGRAM: Threads.c
  12. *
  13. *  PURPOSE:
  14. *
  15. *     To demonstrate multi-threading.
  16. *
  17. *  FUNCTIONS:
  18. *
  19. *    WinMain()      - Initializes a window, and process the message loop.
  20. *    MainWndProc()  - Process messages, launches server & client threads.
  21. *    ThreadProc()   - Draws a rectangle to a window.
  22. *     AsmThreadProc()- Assembly procedure that draws a rectangle to a window.
  23. *
  24. *  COMMENTS:
  25. *
  26. *    To Use:
  27. *      When starting this application, two threads are created.  The
  28. *      first draws a green box, the second a red.  Both boxes are moved
  29. *      about the screen as their individual threads calculate a new
  30. *      position and redraws the box. 
  31. *
  32. *      Note through out the sample "red thread" or "green thread" are
  33. *      referred to.  This simply indicates the thread which draws either the
  34. *      red or green rectangle.
  35. *
  36. \*************************************************************************/
  37.  
  38.  
  39. #include <windows.h>
  40. #include <stdlib.h>
  41. #include <time.h>
  42. #include "threads.h"
  43.  
  44.  
  45.  
  46. /*************************************************************************\
  47. *
  48. *  FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
  49. *
  50. *  PURPOSE: calls initialization function, processes message loop
  51. *
  52. *  COMMENTS:
  53. *
  54. \*************************************************************************/
  55. int APIENTRY WinMain (HANDLE hInstance,
  56.                       HANDLE hPrevInstance,
  57.                       LPSTR  lpCmdLine,
  58.                       int    nCmdShow)
  59. {
  60.   MSG  msg;
  61.   WNDCLASS wc;
  62.  
  63.   UNREFERENCED_PARAMETER( lpCmdLine );
  64.   UNREFERENCED_PARAMETER( hPrevInstance );
  65.  
  66.   hInst = hInstance;
  67.  
  68.   wc.style = 0;                             // Replaces CS_SIZEREDRAW.
  69.   wc.lpfnWndProc = (WNDPROC)MainWndProc;    // The client window procedure.
  70.   wc.cbClsExtra = 0;                         // No room reserved for extra data.
  71.   wc.cbWndExtra = 0;
  72.   wc.hInstance = hInstance;
  73.   wc.hIcon = LoadIcon (NULL, IDI_ASTERISK);
  74.   wc.hCursor = LoadCursor (NULL, IDC_ARROW);
  75.   wc.hbrBackground = GetStockObject (BLACK_BRUSH);
  76.   wc.lpszMenuName = NULL;
  77.   wc.lpszClassName = "ThreadsWClass";
  78.  
  79.   RegisterClass(&wc);
  80.  
  81.  
  82.   hWind = CreateWindow ("ThreadsWClass",
  83.                        "2 Threads     Red = Asm, Green = C",
  84.                        WS_OVERLAPPEDWINDOW,
  85.                        CW_USEDEFAULT,
  86.                        CW_USEDEFAULT,
  87.                        CW_USEDEFAULT,
  88.                        CW_USEDEFAULT,
  89.                        NULL,
  90.                        NULL,
  91.                        hInstance,
  92.                        NULL);
  93.  
  94.  
  95.  
  96.  
  97.  
  98.   ShowWindow(hWind, nCmdShow);
  99.   while (GetMessage (&msg, NULL, 0, 0))
  100.     DispatchMessage (&msg);   // Dispatch message to window.
  101.  
  102.   return (msg.wParam);           // Returns value from PostQuitMessage.
  103.  
  104. }
  105.  
  106. /*************************************************************************\
  107. *
  108. *  FUNCTION:  MainWndProc (hWind, UINT, UINT, LONG)
  109. *
  110. *  PURPOSE:   To process the windows messages. This procedure totally
  111. *             controls the priority of the threads.
  112. *
  113. *  VARIABLES USED:
  114. *
  115. *    - hThread1,hThread2
  116. *             Static handles to the two created threads.
  117. *
  118. *    - ThreadID1, ThreadID2
  119. *             DWORDs used in the CreateThread call.
  120. *
  121. *    - pColor1, pColor2
  122. *             DWORDs used to allocate some memory to use as a parameter
  123. *             to pass color values to the threads.  This memory was
  124. *             allocated so that the threads wouldn't have to rely on this
  125. *             procedures stack for the values.
  126. *
  127. *    - Buf[80]:
  128. *             Character buffer used to write messages to the user.
  129. *
  130. *
  131. *  MESSAGES:
  132. *
  133. *    WM_DESTROY:     - Terminates the threads and post the quit message.
  134. *    WM_CREATE:      - Allocates memory to hold some color values, and
  135. *                      creates the two threads.
  136. *    WM_COMMAND
  137. *
  138. *      
  139. *
  140. *  CALLED BY:
  141. *
  142. *    WinMain();
  143. *
  144. *  CALLS TO:
  145. *
  146. *    ThreadProc();
  147. *     AsmThreadProc();
  148. *
  149. *  COMMENTS:
  150. *
  151. *
  152. \*************************************************************************/
  153.  
  154.  
  155. LONG APIENTRY MainWndProc (HWND hWind,
  156.                            UINT message,
  157.                            UINT wParam,
  158.                            LONG lParam)
  159. {
  160.   static HANDLE hThread1, hThread2;
  161.   DWORD  ThreadID1, ThreadID2;
  162.   CHAR Buf[80];    
  163.   static DWORD *pColor1, *pColor2;
  164.  
  165.   switch (message)
  166.       {
  167.  
  168.         case WM_CREATE :
  169.  
  170.             pColor1 = malloc(sizeof(DWORD));
  171.               *pColor1 = GREEN;
  172.               hThread1 =    CreateThread (NULL, 0,
  173.                            (LPTHREAD_START_ROUTINE)ThreadProc,
  174.                            (LPVOID)pColor1, 0,
  175.                            (LPDWORD)&ThreadID1);
  176.  
  177.             if (!hThread1)
  178.                 {
  179.                  wsprintf(Buf, "Error in creating C Green thread: %d",
  180.                         GetLastError());
  181.                  MessageBox (hWind, Buf, "WM_CREATE", MB_OK);
  182.                 }
  183.             else
  184.                 {
  185.                 SetThreadPriority (hThread1, THREAD_PRIORITY_NORMAL);
  186.                 }
  187.  
  188.               Sleep (500);           // Allow some time/distance between the
  189.                                    // thread boxes.
  190.  
  191.               pColor2 = malloc(sizeof(DWORD));
  192.               *pColor2 = RED;
  193.               hThread2 =     CreateThread (NULL, 0,
  194.                            (LPTHREAD_START_ROUTINE)AsmThreadProc,
  195.                            (LPVOID)pColor2, 0,
  196.                         (LPDWORD)&ThreadID2);
  197.  
  198.           if (!hThread2)
  199.             {
  200.              wsprintf(Buf, "Error in creating Asm thread: %d",
  201.                       GetLastError());
  202.              MessageBox (hWind, Buf, "WM_CREATE", MB_OK);
  203.             }
  204.         else        
  205.             {
  206.             SetThreadPriority (hThread2, THREAD_PRIORITY_NORMAL);
  207.             }
  208.  
  209.         
  210.         return (0);
  211.  
  212.  
  213.         case WM_COMMAND:  
  214.             switch (LOWORD(wParam))
  215.                 {      
  216.                   return (0);
  217.                 }
  218.  
  219.         case WM_DESTROY :                    // When the window is destroyed
  220.             TerminateThread(hThread1, 0);    // terminate the threads
  221.             TerminateThread(hThread2, 0);
  222.             free (pColor1);                    // Free allocated memory.
  223.             free (pColor2);
  224.             PostQuitMessage (0);            // End it.
  225.             return (0);
  226.  
  227.        }
  228.     return DefWindowProc (hWind, message, wParam, lParam);
  229. }
  230.  
  231. /*************************************************************************\
  232. *
  233. *  FUNCTION:  ThreadProc (LPVOID)
  234. *
  235. *  PURPOSE:   A thread procedure which calculates position on the window
  236. *             and draws a colored rectangle.  The color of the rectangle
  237. *             is determined by the input parameter.
  238. *
  239. *  VARIABLES USED:
  240. *
  241. *    - horizontal, vertical:
  242. *             Local int used to indicate the next directional move the
  243. *             rectangle will make.
  244. *
  245. *    - ulx, uly:
  246. *             Local DWORD used for the Upper Left X corner and Upper
  247. *             Upper Left Y position of the rectangle.
  248. *
  249. *    - rect:  A RECT structure used to determin the current size of the
  250. *             window (in case the user resizes it).
  251. *
  252. *    - hdc:   HDC of the rectangle.
  253. *
  254. *    - Time:  A SYSTEMTIME structure.  It's milli-second field is used
  255. *             to create an apparent random starting point for the
  256. *             rectangles.
  257. *
  258. *    -hBrush: A handle to a Brush object, used to set the color of the
  259. *             rectangle.
  260. *
  261. *    -width, height:
  262. *             Local DWORDs used for the width and height of the rectangles.
  263. *
  264. *  CALLED BY:
  265. *
  266. *    MainWndProc();
  267. *
  268. \*************************************************************************/
  269.  
  270.  
  271. VOID ThreadProc ( LPVOID *Color)
  272. {
  273.   int  horizontal, vertical;
  274.   DWORD ulx, uly;
  275.   RECT rect;
  276.   HDC  hDC;
  277.   SYSTEMTIME Time;
  278.   HANDLE hBrush;
  279.   DWORD width, height;
  280.  
  281.   width =  20;
  282.   height = 20;
  283.  
  284.   GetSystemTime (&Time);                     // Get the time.
  285.  
  286.   do{}while(!GetClientRect(hWind, &rect));    // Loop, making sure window
  287.                                              // exists.
  288.  
  289.   ulx = (Time.wMilliseconds % rect.right);   // Use MOD to get a random
  290.   uly = (Time.wMilliseconds % rect.bottom);  // position.
  291.  
  292.   if(Time.wMilliseconds % 2 == 0)            // Use MOD to pick random
  293.     {                                        // directions.
  294.      horizontal = 1;
  295.      vertical = 1;
  296.     }
  297.   else
  298.     {
  299.      horizontal = 1;
  300.      vertical = -1;
  301.     }
  302.                                              // Set color as per input
  303.                                              // parameter.
  304.   hBrush = CreateSolidBrush((COLORREF)*Color);
  305.  
  306.   do
  307.     {                                        // do forever ...
  308.      GetClientRect( hWind, &rect);
  309.  
  310.      if ( (ulx+width) > (DWORD)rect.right)   // ... check for right edge,
  311.       {
  312.       ulx = rect.right - width;
  313.       horizontal = -1;                       //   ... if so change direction;
  314.       }
  315.  
  316.      if ((uly+height) > (DWORD)rect.bottom)  // ... check for bottom edge,
  317.       {
  318.       uly = rect.bottom - height;            //   ... if so change dir.
  319.       vertical = -1;
  320.       }
  321.  
  322.      if (uly <= 1)                           // ... check for right edge,
  323.       {
  324.       uly = 1;
  325.       vertical = 1;
  326.       }
  327.  
  328.      if (ulx <= 1)
  329.       {                                      // ... check for top edge;
  330.       ulx = 1;
  331.       horizontal = 1;
  332.       }
  333.  
  334.      hDC = GetDC(hWind);                      // ... Get DC,
  335.      SelectObject( hDC, hBrush);             // ... Set brush color,
  336.                                              // ... Draw rectangle,
  337.      Rectangle (hDC, ulx, uly, ulx+width, uly+height);
  338.      ReleaseDC(hWind, hDC);                   // ... Release DC
  339.      ulx += horizontal;                      // ... Increment/decrement
  340.      uly += vertical;                        // ... position.
  341.  
  342.     }while(1);
  343. }
  344.